<?php

namespace App\Services\Third;

use App\Constant\CacheConst;
use App\Exceptions\ExceptionHelper;
use Qiniu\Auth;
use Cache;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;

class QiNiu
{
    private $accessKey;
    private $secretKey;

    private $bucket;

    private $expires = 7200;

    public function __construct($accessKey, $secretKey, $bucket)
    {
        $this->accessKey = $accessKey;
        $this->secretKey = $secretKey;
        $this->bucket    = $bucket;
    }

    /**
     * 上传文件
     * filePath 本地文件名
     * fileName 上传到七牛云的文件名
     * @param $filePath
     * @param $fileName
     * @param bool $isDeleteOld  是否删除本地文件
     * @return mixed
     * @throws \Exception
     */
    public function upload($filePath, $fileName, $isDeleteOld = true)
    {
        if ($this->needUploadToken()) {
            $auth = new Auth($this->accessKey, $this->secretKey);
            $upToken = $auth->uploadToken($this->bucket, null, $this->expires);
            $this->cacheUploadToken($upToken); // 缓存token，两小时内有效
        } else {
            $upToken = Cache::get(CacheConst::QI_NIU_YUN_UPLOAD_TOKEN);
        }
        $uploadMgr = new UploadManager();
        $fileName=str_replace('\\','/',$fileName);
        list ($ret, $err) = $uploadMgr->putFile($upToken, $fileName, $filePath);
        if ($err !== null) {
            \Log::warning('文件上传到七牛云失败：' . (is_string($err) ? $err : json_encode($err)));
            throw ExceptionHelper::getInstance(ExceptionHelper::SYSTEM_ERROR);
        } else {
            // 如果需要删除源文件
            if ($isDeleteOld) {
                @unlink($filePath);
            }
            return $ret;
        }
    }

    /**
     * 删除云文件
     * $key  云文件路径
     * @param $key
     * @return array
     * @method：delete
     * @author：wyk
     * @datetime：2021-12-13 11:15
     */
    public function delete($key)
    {

        $auth = new Auth($this->accessKey, $this->secretKey);
        $bucketManager = new BucketManager($auth);
        list ($ret, $err) = $bucketManager->delete(config('common.qi_niu_bucket'), $key);
        if ($err !== null) {
            \Log::warning('云文件删除失败：' . (is_string($err) ? $err : json_encode($err)));
            throw ExceptionHelper::getInstance(ExceptionHelper::SYSTEM_ERROR);
        } else {
            return $ret;
        }
    }

    /**
     * 批量删除云文件
     * $keys 云文件路径数组
     *
     * @param array $keys
     * @return mixed
     * @method：batchDelete
     * @author：wyk
     * @datetime：2021-12-13 11:43
     */
    public function batchDelete(array $keys)
    {
        $auth = new Auth($this->accessKey, $this->secretKey);
        $bucketManager  = new BucketManager($auth);
        $ops = $bucketManager->buildBatchDelete(config('common.qi_niu_bucket'), $keys);
        list($ret, $err) = $bucketManager->batch($ops);
        if ($err !== null) {
            \Log::warning('云批量删除文件失败：' . (is_string($err) ? $err : json_encode($err)));
            throw ExceptionHelper::getInstance(ExceptionHelper::SYSTEM_ERROR);
        } else {
            return $ret;
        }
    }

    /**
     * 判断token是否有效
     * @return bool
     */
    private function needUploadToken()
    {
        $key = CacheConst::QI_NIU_YUN_UPLOAD_TOKEN_EXPIRE;
        $timer = intval(Cache::get($key));
        if ($timer && $timer + $this->expires > time() - 10) {
            return false;
        }
        return true;
    }

    /**
     * @param $token
     */
    private function cacheUploadToken($token)
    {
        Cache::forever(CacheConst::QI_NIU_YUN_UPLOAD_TOKEN, $token);
        Cache::forever(CacheConst::QI_NIU_YUN_UPLOAD_TOKEN_EXPIRE, time());
    }
}
